اسمبلی 2
ما معمولا اعداد را بر پایه ده نشان می دهیم . یعنی اعداد پایه ده. زیرا بعد از شمردن از 0 تا عدد 9 ، اعداد دو رقمی شده و یا به عبارت دیگر یکی به دهگان عدد اضافه می شود .بطور مثال عدد 128 را در نظر بگیرید. این عدد یعنی
128=8*10^0+2*10^1+1*10^2
همانطور متوجه شدید رتبه دهگان و صدگان و هزارگان در واقعه معرف توان ده در رابطه بالا می باشد.بعلت استفاده 10 به عنوان پایه توان این مبنا را ده دهی می گویند.
اعداد در پایه های دیگر هم دارای رابطه ای شبیه رابطه بالا می باشند مثلا رابطه عدد 128 در پایه x بصورت زیر نوشته می گردد:
128(x)=8*x^0+ 2*x^1 +1*x^2
بعد از آشنایی به پایه اعداد و پایه های دیگر بصورت اجمالی حال به بررسی مبناهایی پرداخته می شود که در کامپیوتر کاربرد بسیار دارد.
پایه دو دوبی: ( Binary)
همانطور که از اسم این پایه معلوم است مبنا اعداد در این پایه دو بوده و اعداد تشکیل دهنده این مبنا عبارتند از 0،1(اعداد کوچکتر از پایه با انضمام 0 )یک عدد در این مبنا بصورت مینیمم 1 بیت را مورد استفاده قرار می دهد.2^0=1 ماکزیمم عدد تشکیل دهنده
پایه هشت هشتی یا اکتال
شبیه پایه دو بوده ولی اعداد بکار رفته در آن عبارت است از: 0،1،2،3،4،5،6،7. هر عدد در این مبنا حداقل 3 بیت مورد مصرف قرار
می دهد
2^0+2^1+2^2=7
( هر کدام از جواب به توان رساندن یک بیت را اشغال می نمایید )
پایه هگزا دسیمال (Hex)
اعداد بکار رفته در آن عبارت است از:F،E،D،C،B،A،9،8، 0،1،2،3،4،5،6،7. که در آن A معرف 10و B معرف 11 و ... E معرف 15
می باشد هر عدد در این مبنا حداقل 4 بیت مورد مصرف قرار می دهد
2^0+2^1+2^2+2^3=15
چگونگی تبدیل پایه های دیگر به ده دهی:
برای تبدیل هر عدد در مبنای x به مبنای ده دهی از روش زیر استفاده می کنیم: ( فرض کنید عدد ما در مبنا x برابر QWER می باشد )
QWER(x)=R*x^0+E*x^1+W*x^2+Q*x^3+….
حاصل جمع ما همان عدد در پایه ده دهی (مثلا TYUIO) یعنی
TYUIO(10)=QWER(x)
حال می رسیم به تبدیل اعداد پایه 10 به پایه های دیگر
برای این کار از روش تقسیمهای متوالی استفاده می نماییم عدد را بر پایه مورد نظر ( x ) تقسیم نموده .باقی مانده را در بجای اولین عدد معادل قرار می دهیم حال خارج قسمت را بر x تقسیم نموده و باقی مانده را در کنار باقی مانده قبلی در سمت چپ آن قرار می دهیم آنقدر این کار را انجام داده تا خارج قسمت از x کمتر گردد .حال آخرین خارج قسمت را نیز دز سمت چپ باقی مانده ها قرار می دهیم ( آخرین باقیمانده را نیز قبل از اضافه کردن خارج قسمت به اعداد اضافه می نماییم) عدد حاصله معادل عدد ده دهی در پایه x می باشد.
الگوریتم آن عبارت است از:
1- عدد را بگیر
2- اگر عدد کوچکتر از x است به مرحله6 بپر
3- عدد را بر x تقسیم کن باقیمانده را در سمت چپ عدد معادل کنار اعداد دیگر بنویس اگر عددی نبود آن را یاد داشت کن
4- خارج قسمت را جای عدد بگذار
5- به مرحله 2 برو
6- عدد را به سمت چپ اعداد اضافه کن
7- نمایش رشته
قسمت دوم
دستورات اسمبلی
در این قسمت به شناسایی دستورات اسمبلی می رسیم .
Mov Dest,source
با اجرای این دستور منبع درون مقصد کپی می شود. منبع و یا مقصد می تواند یکی از حالات زیر باشه:
-ثبات یا رجی ستر
-آدرس حافظه
- رجی ستری که به حافظه ای اشاره مکنه
-رجی ستری که به حافظه ای که نسبی اشاره می کنه
( بعدا در نحوه آدرس دهی این مفاهیم توضیح داده می شود)
مثال
Mov eax,ebx
که مقدار ebx تو eax می ریزد.
Push value
وظیفه آن قرار دادن value در Stack memory می باشد.
مثال
Push eax / Push [004044ca]
که مقدار eax را تو پشته قرار می دهد./ مقدارای را که در حافظه [004044ca] می باشد را در پشته قرار می دهد.
Pop value
معکوس Push بوده و مقداری را که با Push در حافظه قرار گرفته را بر می گرداند.
مثال
eax= 10h push eax
eax=1000h mov eax,1000h
ebx=12h mov ebx,12h
ebx=ebx+eax=1012h add ebx,eax
eax=10h Pop eax
×همیشه متغیری که در حافظه قرار میگیرد لزوما با همان متغیر برداشته نمی شود
Push eax
….
Pop ebx
PopA /PushA
دقیقا مثل پدرهاشون می مانند. با این تفاوت که تمامی رجی ستر ها را در حافظه قرار داده یا همگی را می خوانند.
Lea reg,Source
مقدار آدرس موثر(واقعی با سگ منت و افست ) منبع را در رجی ستر قرار می دهد.
Jmp value
اگر value آدرس موثر باشد ( که معمولا نیست ) به آن آدرس برنامه فرستاده می شود .و اگر موثر نباشه به اندازه مقدار value به آدرس کنونی اضافه کرده و به اونجا می رود
اگر یاد تون باشد EIP شماره خط در حال حاضر رو تو خودش دارد پس دو دستور زیر با هم معادل اند:
Jmp 02 ,jump to address that is equal to current address+02
Add EIP +02 , EIP equal to EIP (Current Address)+2
Cmp Op1,Op2
مقدار اولی و دومی را مقایسه می کند . (اولی منهای دومی ) بر اساس نتیجه مقدار رجی ستر وضعیت ( قبلا معرفیشون نکردم فقط وضعیت مقایسه را تو خودش قرار می دن )( شامل بیتهای zf,sf,pf,of,cf,af است ) ست می کند. مهمتر ینشون zf (حاصل تفریق 0 است zf=1 یعنی با هم برابر اند)
Jz,Jnz,…
تمامی دستوراتی که یا z شروع می شن یعنی اگر ... و پرش .مثلا JZ ( Jump if Zero)یعنی اگر بیت zf از رجی ستر وضعیت 1 باشد به خط مورد نظر پرش نما
بیت معادل شرط
zf=1 = Jz=Je
zf=0 != Jnz
zf=0 and cf=0 بزرگتر Ja
cf=0 بزرگترو مساوی Jae
cf=1 کوچکتر Jb
cf=1 or zf=0 کوچکتر و مساوی Jbe
ecx=0 اگر cx برابر 0 شد Jcxz
(دستوراتی هم مثل JGو یا JL و هستن که برای اعداد علامت دار مصرف میشوند که ثبات وضعیتشون یادم نیست به هر صورت خود تون یاد بگیرید.)
ADD و ADC( Adding & Adding With Carry)
هر دو مقدار اول را بعلاوه مقدار دوم کرده و نتیجه را در اولیه می گذارند . قبل از اینکه فرقشون رو بگم بهتر که Overflow رو بگم . در حالت اعداد طبیعی هر بایت نمایانگر یک عدد بین 0 تا 255 می باشد ولی در حالت اعداد صحیح هر بایت نمایانگر یک عدد بین 128- تا 127 است.
بیت معمولی بیت معمولی بیت معمولی بیت معمولی بیت معمولی بیت معمولی بیت معمولی بیت علامت
اگر بیت علامت یک باشد یعنی عدد منفی است و 0 بودن آن یعنی عدد مثبت است .
حال فرض کنیم 96 را با 32 جمع کنیم نتیجه 128 می شود ولی در حالت بالا عدد معادل 0 منفی است که باعث سر ریز شده است .
در حالت جمع ADC این حالت پیش نیامده و همچنین اگر دو بایت را یا هم جمع کردیم و بر16 ) مثل بر 10 ) در جمع آنها را نیز دخالت می دهد. مثلا اگر یک کلمه را با کلمه دیگر جمع کنیم جواب درست نمایش داده می شود.
SUB و SBB
عمل تفریق را انجام می دهد .SBB دارای خصوصیات ADC است ولی عمل تفریق را انجام می دهد.
Neg
علامت عدد را معکوس می نماید. از روش متمم دو
INC x
به عدد x یک عدد اضافه می نماید.( x می تواند حافظه و یا آدرس و یا رجی ستر باشد)
DEC x
از x یک عدد کم می کند.
MUL x
برابر eax=eax*x
IMUL x
مثل mul است ولی برای اعداد علامت دار
DIV x وIDIV x
تقسیم مثل MUL وMULI
جداول عملیاتی
ANDوORوXORوNOTوTest
NOT A
A=NOT A XOR A,B
A=A XOR B AND A,B
A=A AND B OR A,B
A=A OR B B A
1 0 0 0 0 0
1 1 0 1 1 0
0 1 0 1 0 1
0 0 1 1 1 1
عمل TEST A,B مثل عمل AND بوده ولی باعث تغییر A نمی شود .ولی در صورت برابری AوB مقدار zf را یک می کند.